﻿using Microsoft.Ajax.Utilities;
using Microsoft.VisualBasic;
using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using System.Web.UI;
using System.Web.WebPages;

namespace WebApplicationTestJs.Models
{
    //RazorView
    //BuildManagerCompiledView
    public class MyRazorView : RazorView
    {
        public MyRazorView(ControllerContext controllerContext, string viewPath, string layoutPath, bool runViewStartPages, IEnumerable<string> viewStartFileExtensions)
            : base(controllerContext, viewPath, layoutPath, runViewStartPages, viewStartFileExtensions, null)
        {
        }

        public MyRazorView(ControllerContext controllerContext, string viewPath, string layoutPath, bool runViewStartPages, IEnumerable<string> viewStartFileExtensions, IViewPageActivator viewPageActivator)
            : base(controllerContext, viewPath, layoutPath, runViewStartPages, viewStartFileExtensions, viewPageActivator)
        {
        }

        private static Minifier minifier = new Minifier();
        private static CodeSettings codeSettings = new CodeSettings()
        {
            IgnoreAllErrors = true,
            MinifyCode = true,
            LocalRenaming = LocalRenaming.CrunchAll
        };
        private static CssSettings cssSettings = new CssSettings()
        {
            IgnoreAllErrors = true,
            OutputMode = OutputMode.SingleLine,
            MinifyExpressions = true,
        };
        /// <summary>
        /// 匹配<script>xxxxx</script>之间的内容
        /// </summary>
        //private static Regex regexJs = new Regex("(?<=<script(.*?)>)(.|\n)*?(?=</script>)", RegexOptions.IgnoreCase);
        //private static Regex regexJs = new Regex("(?<=<script(.)*?>)(.|\n)*?(?=</script>)", RegexOptions.IgnoreCase);
        //private static Regex regexJs = new Regex("(?<=<script[^>]*>)([\\s\\S](?!<script))*?(?=</script>)", RegexOptions.IgnoreCase);
        //測試證明，這個正則匹配準確高
        private static Regex regexJs = new Regex("(?<=<script(.)*?>)([\\s\\S](?!<script))*?(?=</script>)", RegexOptions.IgnoreCase);
        //string regexstr=@"<script[^>]*>([\s\S](?!<script))*?</script>";

        /// <summary>
        /// 匹配<style>xxxxx</style>之间的内容
        /// </summary>
        //private static Regex regexStyle = new Regex("(?<=<style(.*?)>)(.|\n)*?(?=</style>)", RegexOptions.IgnoreCase);
        private static Regex regexStyle = new Regex("(?<=<style(.)*?>)([\\s\\S](?!<script))*?(?=</style>)", RegexOptions.IgnoreCase);

        private const string keyCss = "[css*.256.843.56.745.h*J.]";
        private const string keyJs = "[js*.869.218.839.*W.]";

        protected override void RenderView(ViewContext viewContext, TextWriter writer, object instance)
        {
            StringWriter stringWriter = new StringWriter();
            HtmlTextWriter tw = new HtmlTextWriter(stringWriter);
            base.RenderView(viewContext, tw, instance);
            string html = stringWriter.ToString();

            //如果不講簡體轉換為繁體，請注釋這行代碼
            //将html里面的简体中文转换为繁体,末尾參數設置為1033為了防止頁面亂碼產生
            html = Microsoft.VisualBasic.Strings.StrConv(html, VbStrConv.TraditionalChinese, 1033);

            Parallel.Invoke(() =>
            {
                //压缩js           
                var marchCollection = regexJs.Matches(html);
                if (marchCollection.Count > 0)
                {
                    foreach (Match item in marchCollection)
                    {
                        if (string.IsNullOrWhiteSpace(item.Value))
                        {
                            continue;
                        }
                        //string jsTemp = item.Value.Replace("<script>", "").Replace("</script>","").Replace("<script type=\"text/javascript\">", "");
                        html = html.Replace(item.Value, keyJs);
                        //压缩js
                        string minJs = minifier.MinifyJavaScript(item.Value, codeSettings);
                        html = html.Replace(keyJs, minJs);                     
                    }
                }
            }
                , () =>
             {
                //压缩css
                //是否有<style>标签
                //var isHaveStyle = Regex.Match(sb.ToString(), "<style(.*)>", RegexOptions.IgnoreCase).Success;
                //匹配style节点         
                var marchList = regexStyle.Matches(html);
                 if (marchList.Count > 0)
                 {
                     foreach (Match item in marchList)
                     {
                         if (string.IsNullOrWhiteSpace(item.Value))
                         {
                             continue;
                         }
                         html = html.Replace(item.Value, keyCss);
                         //压缩style
                         string minCss = minifier.MinifyStyleSheet(item.Value, cssSettings, codeSettings);
                         html = html.Replace(keyCss, minCss);                   
                     }
                 }
             });

             
            ////压缩html，要壓縮html代碼請啟用下列代碼
            ////tHtml = Regex.Replace(tHtml, @"(?<=>)\s|\n|\t(?=<)", string.Empty);
            ////移除html标签之间的空格 
            //html = Regex.Replace(html, @"(?<=>)[\s|\n|\t]*(?=<)", string.Empty);
            ////移除多余空格和换行符
            //html = new Regex(@"\n+\s+").Replace(html, string.Empty);

            //输出到页面
            writer.Write(html);
        }


    }
}